package net.awpspace.relaychat.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

/**
 * Server executable
 * 
 * @author Diep Hoang Savvycom JSC
 * 
 */
public class Server {

	/**
	 * Port of server socket
	 */
	private static final int SERVER_PORT = 8888;

	/**
	 * Server socket
	 */
	private ServerSocket socket;

	/**
	 * Thread management
	 */
	private ArrayList<ServerThread> threads;

	/**
	 * Callback for thread management
	 */
	private ServerThreadCallback callback;

	/**
	 * Constructor
	 */
	private Server() {
		threads = new ArrayList<ServerThread>();
		callback = new ServerThreadCallback() {

			@Override
			public void requestInterrupt(ServerThread thread) {
				System.out.println("Requesting: Interrupt "
						+ thread.getChatId());
				thread.stopRunning();
				threads.remove(thread);
			}

			@Override
			public boolean requestFriend(String chatId) {
				for (ServerThread thread : threads) {
					if (thread.getChatId().equals(chatId)) {
						return true;
					}
				}
				return false;
			}

			@Override
			public void sendMessage(String msg, String friendId) {
				for (ServerThread thread : threads) {
					if (thread.getChatId().equals(friendId)) {
						thread.sendMessage(msg);
						return;
					}
				}
			}
		};
	}

	/**
	 * Application entry point
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		Server server = new Server();
		System.out.println("Initializing...");
		if (server.init()) {
			System.out.println("Server is ready");
			server.start();
		}
	}

	/**
	 * Initialization
	 * 
	 * @return
	 */
	private boolean init() {
		try {
			socket = new ServerSocket(SERVER_PORT);
		} catch (IOException e) {
			System.out.println("System error");
			return false;
		}
		return true;
	}

	/**
	 * Listening loop
	 */
	private void start() {
		while (true) {
			Socket client = null;
			try {
				client = socket.accept();
			} catch (IOException e) {
				System.out.println("IO error: " + e.getMessage());
			}
			if (client != null) {
				ServerThread thread = new ServerThread(client.getInetAddress()
						.getHostAddress() + ':' + client.getPort(), client,
						callback);
				threads.add(thread);
				thread.start();
				System.out.println("Connection etablished from "
						+ thread.getChatId());
			}
		}
	}
}
